package com.infore.siteManagement.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.infore.siteManagement.constant.Constants;
import com.infore.siteManagement.constant.ResultConstants;
import com.infore.siteManagement.dto.EquipmentAndProjectDto;
import com.infore.siteManagement.entity.Equipment;
import com.infore.siteManagement.entity.EquipmentType;
import com.infore.siteManagement.entity.ProjectAndEquipment;
import com.infore.siteManagement.entity.Station;
import com.infore.siteManagement.enums.EquipmentValidate;
import com.infore.siteManagement.enums.ResultStatus;
import com.infore.siteManagement.repository.IEquipmentRepository;
import com.infore.siteManagement.repository.IProjectAndEquipmentRepository;
import com.infore.siteManagement.repository.IndexRespository;
import com.infore.siteManagement.select.QueryDispatcher;
import com.infore.siteManagement.select.dto.QueryParamDto;
import com.infore.siteManagement.select.util.PageObject;
import com.infore.siteManagement.select.util.QueryUtil;
import com.infore.siteManagement.service.EquipmentService;
import com.infore.siteManagement.util.ArrayUtils;
import com.infore.siteManagement.util.DateUtil;
import com.infore.siteManagement.util.MyBeanUtils;
import com.infore.siteManagement.util.PageUtil;
import com.infore.siteManagement.util.ResultEntity;
import com.infore.siteManagement.util.UUIDGenerator;

/**
 * 设备管理实现层
 * 
 * @author 刘乐法
 *
 *
 */
@Service
public class EquipmentServiceImpl implements EquipmentService {

	@Autowired
	private IEquipmentRepository iEquipmentRepository;
	@Autowired
	private QueryDispatcher queryDispatcher;
	@Autowired
	private IndexRespository iIndexRespository;
	@Autowired
	private IProjectAndEquipmentRepository iProjectAndEquipmentRepository;

	public ResultEntity deleteEquipmEntity(String ids) {
		// 判断是否含“,”，是则拆分否则删除单个
		try {
			if (ids.contains(",")) {
				List<String> idsList = Arrays.asList(ids.split(","));
				iEquipmentRepository.deleteByEquipmentIdIn(idsList);
			} else {
				iEquipmentRepository.deleteById(ids);
			}
		} catch (Exception e) {
			return new ResultEntity(ResultStatus.ERROR, ResultConstants.EQUIPMENT_DELETE_ERROR);
		}
		return new ResultEntity(ResultStatus.SUCCESS, ResultConstants.EQUIPMENT_DELETE_SUCCESS);
	}

	public ResultEntity queryEquipment(QueryParamDto queryParamDto) {
		// 无任何条件查询
		if (queryParamDto == null) {
			List<Equipment> list = iEquipmentRepository.findAll();
			return new ResultEntity(ResultStatus.SUCCESS, ResultConstants.EQUIPMENT_QUERY_SUCCESS).setDataList(list);
			// 只分页
		} else if (queryParamDto.getPageObject() != null && queryParamDto.getAssembleCondition() == null
				&& queryParamDto.getAssembleSql() == null && queryParamDto.getQueryCondition() == null) {
			Page<Equipment> equipmentPage = iEquipmentRepository
					.findAll(queryParamDto.getPageObject().getPageRequest());
			com.infore.siteManagement.util.Page<Equipment> page = PageUtil.pageConvert(equipmentPage);
			return new ResultEntity(ResultStatus.SUCCESS, ResultConstants.EQUIPMENT_QUERY_SUCCESS).setPage(page);
			// 不指定字段查询且不是多对多
		} else if (StringUtils.isBlank(queryParamDto.getAssembleSql().getSelect())) {
			return this.queryAll(queryParamDto);
			// 如果是多对多且指定字段
		}
		return queryDispatcher.dispatcher(queryParamDto, Equipment.class);
	}

	@SuppressWarnings("serial")
	public ResultEntity queryAll(QueryParamDto queryParamDto) {
		// 判断是否分页
		if (queryParamDto.getPageObject() != null) {
			Page<Equipment> projectPage = iEquipmentRepository.findAll(new Specification<Equipment>() {
				public Predicate toPredicate(Root<Equipment> root, CriteriaQuery<?> query,
						CriteriaBuilder criteriaBuilder) {
					// 构建条件
					List<Predicate> predicates = com.infore.siteManagement.select.util.QueryUtil
							.createQueryCondition(queryParamDto, criteriaBuilder, root);
					// 组装条件
					Predicate predicate = com.infore.siteManagement.select.util.QueryUtil
							.assembleCondition(queryParamDto, criteriaBuilder, predicates);
					QueryUtil.assembleSql(queryParamDto, criteriaBuilder, query, root, predicate);
					return query.getRestriction();
				}
			}, queryParamDto.getPageObject().getPageRequest());
			// 分页转换成指定类型的分页
			com.infore.siteManagement.util.Page<Equipment> page = PageUtil.pageConvert(projectPage);
			return new ResultEntity(ResultStatus.SUCCESS, ResultConstants.EQUIPMENT_QUERY_SUCCESS).setPage(page);
		} else {
			// 不分页查询
			List<Equipment> list = iEquipmentRepository.findAll(new Specification<Equipment>() {
				public Predicate toPredicate(Root<Equipment> root, CriteriaQuery<?> query,
						CriteriaBuilder criteriaBuilder) {
					// 构建条件
					List<Predicate> predicates = com.infore.siteManagement.select.util.QueryUtil
							.createQueryCondition(queryParamDto, criteriaBuilder, root);
					// 组装条件
					Predicate predicate = com.infore.siteManagement.select.util.QueryUtil
							.assembleCondition(queryParamDto, criteriaBuilder, predicates);
					QueryUtil.assembleSql(queryParamDto, criteriaBuilder, query, root, predicate);
					return query.getRestriction();
				}
			});
			return new ResultEntity(ResultStatus.SUCCESS, ResultConstants.EQUIPMENT_QUERY_SUCCESS).setDataList(list);
		}
	}

	/** 注意！！编辑时equipmentP为空 **/
	public ResultEntity editEquipment(Equipment equipment) {
		if (StringUtils.isNotBlank(equipment.getEquipmentId())) {
			Equipment oldEquipment = iEquipmentRepository.findById(equipment.getEquipmentId()).orElse(null);
			// 判断是否存在，不存在进行新增，存在则进行编辑，并且防止null值覆盖已有值
			if (oldEquipment != null) {
				EquipmentType oldEquipmenttype = oldEquipment.getEquipmentType();// type
				EquipmentType nEquipmenttype = equipment.getEquipmentType();
				MyBeanUtils.copyNonNullProperties(nEquipmenttype, oldEquipmenttype);
				equipment.setEquipmenttype(oldEquipmenttype);
				MyBeanUtils.copyNonNullProperties(equipment, oldEquipment);
				equipment = oldEquipment;
			} else {
				return new ResultEntity(ResultStatus.ERROR, ResultConstants.NO_SUCH_OBJECT);
			}
		} else {
			// 新增时给设备关联因子和站点
			Station station = equipment.getStation();
			Set<Equipment> equipments = new HashSet<Equipment>();
			station.setEquipment(equipments);
			equipments.add(equipment);
		}
		// 验证设备和设备类型
		ResultEntity resultEntity = validateEquipment(equipment);
		try {
			if (resultEntity.getCode() == 1) {
				return resultEntity;
			} else {
				iEquipmentRepository.saveAndFlush(equipment);
				return new ResultEntity(ResultStatus.SUCCESS, Constants.DEAL_SUCCESS);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return new ResultEntity(ResultStatus.ERROR, Constants.DEAL_FAILUE);
		}
	}

	public ResultEntity validateEquipment(Equipment equipment) {
		// 验证设备和设备类型
		String message = EquipmentValidate.EQUIPMENT_SUCCESS.getResoString();
		EquipmentType equipmenttype = equipment.getEquipmentType();
		if (equipment.getEquipmentName().length() > 500) {
			message = EquipmentValidate.EQUIPMENT_NAME_LENTTH.getResoString();
		}
//		else if (equipment.getEquipmentModel().length() > 50) {
//			message = EquipmentValidate.EQUIPMENT_MODEL_LENGTH.getResoString();
//		}
		else if (equipment.getFixedAssetsCode().length() > 50) {
			message = EquipmentValidate.FIXED_ASSETS_CODE_LENGTH.getResoString();
		} else if (equipment.getManufactureCode().length() > 50) {
			message = EquipmentValidate.MANUFACTURE_CODE_LENGTH.getResoString();
		}
		// else if (equipment.getCreatePeopleName().length() > 50) {
		// message = EquipmentValidate.CREATE_PEOPLE_NAME_LENGTH.getResoString();
		// }
		else if (equipmenttype.getEquipmentTypeName().length() > 50) {
			message = EquipmentValidate.EQUIPMENT_TYPE_NAME_LENGTH.getResoString();
		} else if (equipmenttype.getEquipmentTypeCode().length() > 10) {
			message = EquipmentValidate.EQUIPMENT_TYPE_CODE_LENGTH.getResoString();
		} else if (equipmenttype.getRemark().length() > 50) {
			message = EquipmentValidate.EQUIPMENT_TYPE_REMARK.getResoString();
		} else if (equipmenttype.getLastUpdatePeople().length() > 32) {
			message = EquipmentValidate.EQUIPMENT_TYPE_NAME_LENGTH.getResoString();
		}
		if (!message.equals(EquipmentValidate.EQUIPMENT_SUCCESS.getResoString())) {
			return new ResultEntity(ResultStatus.ERROR, message);
		} else {
			return new ResultEntity(ResultStatus.SUCCESS, message);
		}
	}

	public ResultEntity addEquipmentAndProject(EquipmentAndProjectDto dto) {
		// 得到仪器和参数中间表主键
		String projectId = iIndexRespository.findIdByCode(dto.getProjectCode());
		String equipmentId = UUIDGenerator.getUUID();
		ProjectAndEquipment pe = new ProjectAndEquipment();
		if (StringUtils.isBlank(equipmentId) || StringUtils.isBlank(projectId)) {
			return new ResultEntity(ResultStatus.ERROR, "新增失败");
		}
		pe.setProjectId(projectId);
		pe.setEquipmentId(equipmentId);
		String detectionLimit = dto.getDetectionLimit() == null ? "" : dto.getDetectionLimit();
		pe.setDetectionLimit(detectionLimit);
		String lowerLimit = dto.getLowerLimit() == null ? "" : dto.getLowerLimit();
		pe.setLowerLimit(lowerLimit);
		String upperLimit = dto.getUpperLimit() == null ? "" : dto.getUpperLimit();
		pe.setUpperLimit(upperLimit);
		String reagent = dto.getReagent() == null ? "" : dto.getReagent();
		pe.setReagent(reagent);
		String analyMethons = dto.getAnalyticalMethods() == null ? "" : dto.getAnalyticalMethods();
		pe.setAnalyMethons(analyMethons);
		String equipmentName = dto.getEquipmentName() == null ? "" : dto.getEquipmentName();
		String manufactureCode = dto.getManufactureCode() == null ? "" : dto.getManufactureCode();
		String manufactor = dto.getManufactor() == null ? "" : dto.getManufactor();
		String isenable = dto.getIsenable() == null ? "" : dto.getIsenable();
		String stationMn = dto.getStationMn() == null ? "" : dto.getStationMn();
		String stationName = dto.getStationName() == null ? "" : dto.getStationName();
		String equipmentModel = dto.getEquipmentModel() == null ? "" : dto.getEquipmentModel();
		String equipmentOrange = dto.getEquipmentOrange() == null ? "" : dto.getEquipmentOrange();
		// 用于返回mn号
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		Map<String, String> map = new HashMap<String, String>();
		map.put("stationMn", stationMn);
		list.add(map);
		Date createTime = new Date();
		if (StringUtils.isNotBlank(dto.getCreateTime())) {
			createTime = DateUtil.stringToDate(dto.getCreateTime(), DateUtil.DATE_FULL_STR);
		} else {
			createTime = DateUtil.getSystemTime();
		}
		try {
			iProjectAndEquipmentRepository.saveAndFlush(pe);
			iEquipmentRepository.insertEquipment(equipmentId, equipmentName, manufactureCode, manufactor, isenable,
					stationMn, stationName, createTime, equipmentModel, equipmentOrange);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new ResultEntity(ResultStatus.SUCCESS, Constants.INSERT_SUCCESS).setDataList(list);
	}

	public ResultEntity editEquipmentAndProject(EquipmentAndProjectDto dto) {
		String projectId = iIndexRespository.findIdByCode(dto.getProjectCode());
		String id = dto.getId();
		ProjectAndEquipment pe = iProjectAndEquipmentRepository.findOneById(id);
		String equipmentId = pe.getEquipmentId() == null ? "" : pe.getEquipmentId();
		String equipmentName = dto.getEquipmentName() == null ? "" : dto.getEquipmentName();
		String manufactureCode = dto.getManufactureCode() == null ? "" : dto.getManufactureCode();
		String manufactor = dto.getManufactor() == null ? "" : dto.getManufactor();
		String isenable = dto.getIsenable() == null ? "" : dto.getIsenable();
		String stationMn = dto.getStationMn() == null ? "" : dto.getStationMn();
		String stationName = dto.getStationName() == null ? "" : dto.getStationName();
		String equipmentModel = dto.getEquipmentModel() == null ? "" : dto.getEquipmentModel();
		String equipmentOrange = dto.getEquipmentOrange() == null ? "" : dto.getEquipmentOrange();
		pe.setEquipmentId(equipmentId);
		pe.setProjectId(projectId);
		pe.setDetectionLimit(dto.getDetectionLimit());
		pe.setLowerLimit(dto.getLowerLimit());
		pe.setUpperLimit(dto.getUpperLimit());
		pe.setReagent(dto.getReagent());
		pe.setAnalyMethons(dto.getAnalyticalMethods());
		// 用于返回mn号
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		Map<String, String> map = new HashMap<String, String>();
		map.put("stationMn", stationMn);
		list.add(map);
		Date createTime = new Date();
		if (StringUtils.isNotBlank(dto.getCreateTime())) {
			createTime = DateUtil.stringToDate(dto.getCreateTime(), DateUtil.DATE_FULL_STR);
		} else {
			createTime = DateUtil.getSystemTime();
		}
		try {
			iProjectAndEquipmentRepository.saveAndFlush(pe);
			iEquipmentRepository.updateEquipment(equipmentId, equipmentName, manufactureCode, manufactor, isenable,
					stationMn, stationName, createTime, equipmentModel, equipmentOrange);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new ResultEntity(ResultStatus.SUCCESS, Constants.UPDATE_SUCCESS).setDataList(list);
	}

	public ResultEntity queryInstrumentParameters(String mn, PageObject page) {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			List<String> mnList = ArrayUtils.stringToList(mn);
			List<String> eqList = iEquipmentRepository.findIdsByStationMn(mnList);
			list = iProjectAndEquipmentRepository.selectEquipmentAndProject(eqList);
			if (page != null && page.getPageNumber() != null && page.getPageSize() != null) {
				com.infore.siteManagement.util.Page<Map<String, Object>> result = PageUtil.inventedPage(list, page);
				return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(result);
			} else {
				return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
			}
		} catch (Exception e) {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
		}

	}

}
